package com.ts.auth.controller;

import com.alibaba.fastjson.JSON;
import com.ts.auth.dto.UserLoginDto;
import com.ts.auth.vo.LoginVo;
import com.ts.common.core.exception.TSException;
import com.ts.common.core.utils.IpUtils;
import com.ts.common.core.utils.JWTUtils;
import com.ts.common.core.utils.Result;

import com.ts.feign.api.UserOperationService;
import com.ts.feign.api.UserService;
import com.ts.feign.dto.TopicDTO;
import com.ts.feign.dto.UserDTO;
import com.ts.feign.dto.UserLoginDTO;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@RestController
@RefreshScope
public class UserLoginController {

    /**
     * 12小时后过期
     */
    private final static long EXPIRE = 3600 * 1000 * 12;

    @Autowired
    private RedisTemplate redisTemplate;

    private String loginSmsKey = "ts:notice:login:%s-%s"; // ts:notice:login:10086-0123

    @Autowired
    private UserService userService;

    @Autowired
    private UserOperationService operationService;

    @PostMapping("/login")
    public Result login(HttpServletRequest request, @RequestBody LoginVo loginVo) {

        String mobile = loginVo.getMobile();
        String code = loginVo.getCode();

        // 1.非空校验
        if (StringUtils.isBlank(mobile)) {
            throw new TSException("手机号不能为空");
        }

        if (StringUtils.isBlank(code)) {
            throw new TSException("验证码不能为空");
        }

        // 2.判断验证码
        String key = String.format(loginSmsKey, mobile, code);
        Boolean delete = redisTemplate.delete(key); // 直接删除，解决了原子性的问题
        if (!delete) {
            return new Result().error("验证码有误");
        }

        // 3.到这里就说认证成功了，还要给用户一个凭证，下来带过来我就知道你是谁了？
        // 判断一下这个手机号是否已经注册了，没有注册自动注册一个
        UserDTO userDTO = userService.getUserByMobile(mobile);
        if (userDTO == null) {
            // 说明这个手机号是第一次登录,需要自动注册
            userDTO = new UserDTO();
            userDTO.setMobile(mobile); // 手机号必填的
            String mobileEnd = mobile.substring(mobile.length() - 4);
            userDTO.setUsername("TS-" + mobileEnd); // 自动生成的一个用户名(千锋3737，随机用户名(调用API))
//            userDTO.setCreateTime(new Date());
            userDTO.setLastLoginIp(IpUtils.getIpAddr(request));
            userDTO = userService.addUser(userDTO); // 返回主键

        }

        // 4.登录成功后需要生成Token对象
        UserLoginDto userLoginDto = new UserLoginDto();
        userLoginDto.setUserId(userDTO.getId().intValue());
        userDTO.setLastLoginIp(IpUtils.getIpAddr(request));
        userDTO.setOpenid(null);
        userDTO.setStatus(null);
        userDTO.setMobile(null);
//        userLoginDto.setExpireTime(new Date(+3000));

        // 5.使用JWT生成一个令牌，把userLoginDto放在令牌中,设置过期时间
        String token = JWTUtils.createToken("loginUser", userLoginDto,EXPIRE);

        Map<String, Object> data = new HashMap<>();
        data.put("token", token);
        data.put("userInfo", JSON.toJSONString(userDTO));

        //登录成功后记录日志
        UserLoginDTO userLoginDTO = new UserLoginDTO();
//        userLoginDTO.setLoginTime(new Date());
        userLoginDTO.setIp(IpUtils.getIpAddr(request));
        userLoginDTO.setDevice("设备" + RandomStringUtils.random(2,false,true));
        userLoginDTO.setUserId(userDTO.getId().intValue());
        userLoginDTO.setStatus(1);
        operationService.addUserOpe(userLoginDTO);

        return new Result().viewOk(data);
    }

    @PostMapping("/logout")
    public Result logout(HttpServletRequest request,UserLoginDto userLoginDto){
        //退出成功后记录日志
        UserLoginDTO userLoginDTO = new UserLoginDTO();
//        userLoginDTO.setLoginTime(new Date());
        userLoginDTO.setIp(IpUtils.getIpAddr(request));
        userLoginDTO.setDevice("设备退出");
        userLoginDTO.setUserId(userLoginDto.getUserId());
        userLoginDTO.setStatus(2);
        operationService.addUserOpe(userLoginDTO);

        return new Result().viewOk(null);

    }

}
